use crate::rtmp::messages::define::msg_type_id;
use crate::rtmp::protocol_control_messages::errors::ControlMessagesError;
use byteorder::BigEndian;
use bytesio::bytes_writer::AsyncBytesWriter;

// 定义协议控制消息写入器结构体
pub struct ProtocolControlMessagesWriter {
    writer: AsyncBytesWriter,
}

impl ProtocolControlMessagesWriter {
    pub fn new(writer: AsyncBytesWriter) -> Self {
        Self { writer }
    }

    // 写入控制消息头部
    pub fn write_control_message_header(
        &mut self,
        msg_type_id: u8,
        len: u32,
    ) -> Result<(), ControlMessagesError> {
        // 写入格式和块流ID---->格式0和块流ID2（0x0 << 6 | 0x02）
        self.writer.write_u8(0x02)?;
        // 写入时间戳（3字节，值为0）
        self.writer.write_u24::<BigEndian>(0)?;
        // 写入消息长度
        self.writer.write_u24::<BigEndian>(len)?;
        // 写入消息类型ID
        self.writer.write_u8(msg_type_id)?;
        // 写入消息流ID（4字节，值为0）
        self.writer.write_u32::<BigEndian>(0)?;

        Ok(())
    }

    // 异步写入设置块大小消息
    pub async fn write_set_chunk_size(
        &mut self,
        chunk_size: u32,
    ) -> Result<(), ControlMessagesError> {
        // 写入控制消息头部
        self.write_control_message_header(msg_type_id::SET_CHUNK_SIZE, 4)?;
        // 写入块大小（最高位必须为0）
        self.writer
            .write_u32::<BigEndian>(chunk_size & 0x7FFFFFFF)?;

        self.writer.flush().await?;
        Ok(())
    }

    // 异步写入中断消息
    pub async fn write_abort_message(
        &mut self,
        chunk_stream_id: u32,
    ) -> Result<(), ControlMessagesError> {
        // 写入控制消息头部
        self.write_control_message_header(msg_type_id::ABORT, 4)?;
        // 写入块流ID
        self.writer.write_u32::<BigEndian>(chunk_stream_id)?;

        self.writer.flush().await?;
        Ok(())
    }

    // 异步写入确认消息
    pub async fn write_acknowledgement(
        &mut self,
        sequence_number: u32,
    ) -> Result<(), ControlMessagesError> {
        // 写入控制消息头部
        self.write_control_message_header(msg_type_id::ACKNOWLEDGEMENT, 4)?;
        // 写入序列号
        self.writer.write_u32::<BigEndian>(sequence_number)?;

        self.writer.flush().await?;
        Ok(())
    }

    // 异步写入窗口确认大小消息
    pub async fn write_window_acknowledgement_size(
        &mut self,
        window_size: u32, // 窗口大小
    ) -> Result<(), ControlMessagesError> {
        // 写入控制消息头部
        self.write_control_message_header(msg_type_id::WIN_ACKNOWLEDGEMENT_SIZE, 4)?;
        // 写入窗口大小
        self.writer.write_u32::<BigEndian>(window_size)?;

        self.writer.flush().await?;
        Ok(())
    }

    // 异步写入设置对等带宽消息
    pub async fn write_set_peer_bandwidth(
        &mut self,
        window_size: u32,
        limit_type: u8,
    ) -> Result<(), ControlMessagesError> {
        // 写入控制消息头部
        self.write_control_message_header(msg_type_id::SET_PEER_BANDWIDTH, 5)?;
        // 写入窗口大小
        self.writer.write_u32::<BigEndian>(window_size)?;
        // 写入限制类型
        self.writer.write_u8(limit_type)?;

        self.writer.flush().await?;

        Ok(())
    }
}
